NoSQL
몽고디비
- 문서 기반(Document Oriented) 데이터 저장소.
- 키-값 기반 저장소의 문제점인 질의가 어렵다는 점과 관계형 데이터베이스의 확장성 문제를 해결.
- 싱글 머신, 마스터-슬레이브, 복제-셋(Replica-set), 샤드(shard) 구성 등 요구 사항에 따라 다양한 구성 가능.
- SourceForge, github, 뉴욕타임즈 등 많은 레퍼런스 확보.
데이터 모델과 인덱스
- 문서 기반 데이터 모델을 사용
- 단순한 데이터 모델
- 일반적으로 정적으로 스키마를 정의할 필요가 없는 스키마 프리(schema-free) 특징.
- 운영 중에도 요구사항의 변경 등에 유연하게 대처
- 스키마변경시 발생할 수 있는 테이블 락 문제 없음.
- 문서의 모든 필드에 대해 인덱스 생성 가능.
- 문서 ID(Document ID)는 기본적으로 인덱스 생성.(인덱스 제거 불가)
db.<collection name>.ensureIndex( {<field anme>, <1(desc), -1(asc)>} )
예: db.blog.ensureIndex ( {author, 1} )
- 위치 기반의 검색을 위한 위치 공간(geospacial)인덱스 제공.
- 몽고디비의 데이터 모델 구성 요소
- 문서(Document)
- 여러개의 '필드명, 필드값'쌍
- 문서단위로 저장, 삭제, 수정 가능.(문서 내에 있는 필드 단위로는 수정 불가)
- 문서의 저장과 전송 포멧은 BSON포멧 사용(JSON 타입을 바이너리 인코딩으로 전환)
- 데이터 크기는 4MB로 제한(4MB 이상의 데이터를 저장하려면 GridFS라는 파일 시스템과 연동해 구성)
- 컬렉션(Collection)
- 문서의 그룹으로 관계형 데이터베이스의 테이블과 유사한 개념.
- 네임스페이스로만 의마가 있으며, 컬렉션 내부에는 서로 다른 문서나 문서에 저장되는 필드가 같을 필요는 없다.
- 데이터베이스(Database)
- 관계형 데이터베이스의 데이터베이스 인스턴스와 동일한 개념(컬렉션을 관리하는 단위)
데이터 복제와 샤딩
- 데이터를 복제해 저장하는 방식으로 안정성 지원
- 확장성을 지원하기 위해 오토 샤딩(sharding)방식 이용, 키 기반으로 데이터 분산
- 복제와 샤딩은 별도로 구성 가능.
- 마스터-슬레이브 복제
- 마스터 : 서버 시작시 'master'옵션으로 시작
- 슬레이브 : 시작시 마스터 서버를 지정하고 옵션으로 'slave'값을 이용하여 시작.
- 마스터 서버의 작업 로그 데이터를 이용해 데이터를 복제
- 마스터 서버 장애시에는 읽기 연산만 가능.
- 복제-셋(Replica-Set)
- 명시적으로 마스터, 슬레이브를 지정하지 않고 상황에 따라 마스터가 선정.
- 여러대의 서버에 몽고디비를 실행하고 이 서버들을 복제-셋 환경 설정을 통해 클러스터로 묶으면
서버들 사이에서 임의의 서버가 마스터가 돼 클라이언트의 요청을 처리. - 아비터(arbiter) : 클러스터 내에 마스터 선출을 담당하는 서버
- 아비터를 지정하지 않으면 네트워크가 단절된 상황에서 두 서버가 모두 마스터로 동작(정합성 문제)
- 샤딩
- 임의의 필드로 샤딩 지정가능.
- mongod : 데이터를 저장, 관리하는 서버 (복제 정책도 적용 가능)
- mongod(configsvr) : 샤딩에 대한 환경 설정 서버로, 파티셔닝에 대한 정보를 관리하는 서버.(--configsvr옵션으로 시작)
- mongod서버, 샤딩 정보, 청크에 대한 메타 정보를 관리.
- 1대나 3대로 구성(모두 동일 데이터를 가진다)
- 환경 설정 서버 중 한대라도 장애가 발생하면 청크의 분리, 이동 등의 작업은 수행되지 않는다.
(읽기 모드로 동작, 데이터 처리는 정상적으로 가능)
- mongos : 클라이언트의 요청을 받아 환경 설정 서버의 파티셔닝 정보를 참고해
적절한 데이터 서버로 요청을 포워딩하는 역할을 수행하는 서버. - 샤딩된 서버내에서 저장하는 데이터를 청크(chunk)라 한다.
- 청크가 일정 크기이상(100MB)이 되면 데이터를 2개의 청크로 분리.(서로 다른 서버로 전송)
- 샤딩의 기준이 된 필드를 지정하여 데이터 질의 시 특정 서버에 접속해 데이터 처리
- 다른 필드로 지정하는 경우 전체 서버에 대해 수행(질의 종류에 따라 순차적 or 병렬로 처리)

설치와 실행
- 리눅스, 윈도우즈, 솔라리스 등 대부분의 환경을 지원
- 32비트 운영체제에서는 저장할 수 있는 전체 데이터의 크기가 2GB로 제한.
(메모리 맵(Memory-Mapped)파일 사용. 주소 공간을 가르키는 변수의 길이로 인해) - 간단히 압축만 해제하면 설치 끝.
- 몽고디비에서 데이터를 관리하는 데몬은 mongod

- CLI 기반의 쉘 제공
- for문과 같은 제어문의 사용 가능, 자바스크립트 문법을 이용
- 데이터(Document) 연산 지원
- 문서 생성: save()
- 문서 조회: find(), count()
- 문서 수정: update()
- 문서 삭제: remove()
- 인덱스 생성: ensureIndex()
- 집합연산: group(), min(), max()
- 검색: in, where
- db."컬렉트명",api() 형태로 명령 수행.
- 데이터 관리 예는 p.421 리스트 7.20 참고
bin/mongod --dbpath /home/mongodb/data --port 1234 --rest --fork --logpath /home/mongodb/logs/server.log
- 종료
- db.shutdownServer()
- 운영체제의 kill 명령 실행.
- SIGINT(-2)나 SIGTER(-15) 옵션이용
- SIGKILL(-9)를 이용할 경우 정상적인 종료 작업이 완료되지 않을 수 있으며, repairDatabase 명령으로 복구.
가용성, 확장성 구성
- 데이터베이스의 상태 정보 제공
bin/mongostat --host localhost --port 1234

- --rest 옵션을 주고 mongod를 실행하면 모니터링용 웹 포트 오픈
http://127.0.0.1:2234

- 복제-셋 구성
- 최소 2대 이상의 서버가 필요(실제 3대이상 필요)
- 정족수 기반으로 프라이머리 서버를 선출, 한 대의 서버만 남게 되면 서비스 불가능(프라이머리 서버 선출 불가)
- 2대의 데이터 서버와 1대의 아비터 서버로 구성
- 서버 3대를 --replSet 옵션으로 실행.
- replSet 옵션 다음에 입력한 값은 복제-셋을 식별하는 식별자.(환경 설정시 id로 사용)
- p423 리스트 7.21 참고
- 프라이머리 서버로만 접속해 데이터 작업을 할 수 있다.(이 외 서버에 질의시 에러 발생)
- 프라이머리 서버에 장애가 발생하면 세컨드리 서버가 프라이머리 서버로 선출돼 장애 없이 데이터 처리 가능.
- 위의 경우 클라이언트 드라이버는 자동으로 변경된 프라이머리 서버로 접속.
- 클라우드 서비스에서는 복제 구성과 샤드 구성 모두 가능하게 설치한다(확장성, 가용성 지원위해)

- 서버 3대에 환경 설정 서버와 mongod를 다른 포트 2개 실행.
- 서버1, 서버2의 동일한 포트에 mongod를 복제-셋으로 구성.
- p425 리스트 7.22 참고
예제 프로그램
- 데이터 작업을 하기 위해서는 몽고디비에서 제공하는 클라이언트 라이브러리를 다운로드해 사용.
- 지원 언어는 C/C++, 자바, 자바스크립트, 펄, PHP, 파이썬, 루비 등
- 언어별 라이브러리를 드라이버(Driver)라고 한다.
- 몽고디비 데이터 처리 예제는 p428,429 참고
- 프라이머리 서버에 장애가 발생하면 클라이언트가 재접속하는 것은 몽고디비 클라이언트 드라이버에서 자동 처리.(p.429)
- 샤딩 구성에서 클라이언트는 mongos 서버로 접속
- mongos 서버가 여러 대인 구성에서는 DNS 라운드로빈이나 L4 로드밸런스를 이용
- 자바 클라이언트 코드는 Mongo 클래스 내에 커넥션 풀 기능을 가진다.
(기본 10, 시스템 설정의 MONGO.POOLSIZE or Mongo 객체 생성시 MongoOption 파라미터 이용하여 조절)
맵리듀스
- 자체적으로 지원.
- 클라이언트는 mongos 서버를 통해 맵리듀스 프로그램을 실행하면
mongos는 샤딩 분산 정보를 이용해 각 서버에서 맵리듀스를 실행시킨다. - db.runCommand()나 컬렉션의 mapReduce() 명령을 이용해 실행.
- 맵, 리듀스 함수는 자바 스크립트 함수로 정의
- 옵션
- query : 작업의 입력 데이터를 위한 질의
- sort : query에 대한 정렬 옵션
- limit : 입력 데이터로부터 작업으로 전달되는 객체의 수
- out : 작업 결과 컬렉션명
- keeptemp : 작업 결과 컬렉션명을 지정하지 않으면 임시 컬렉션으로 저장.
클라이언트 세션이 종료될 때 false로 설정되 있으면 임시 컬렉션은 자동으로 삭제.(default false) - finalize : 작업이 종료될 때 모든 객체에 수행되는 함수
- scope : 자바 스크립트의 글로벌 변수 영역에서 사용할 필드 지정
- verbose : 작업 결과 통계 정보를 표시할지 여부를 지정
MySQL 분산 구성
- 복제 기반의 마스터-슬레이브 구성을 통해 데이터의 안정성과 읽기 연산에 대해 가용성을 보장.
- 여러 개의 슬레이브 노드를 이용함으로써 부하를 분산하는 효과.
MySQL 마스터-슬레이브
- 복제는 비동기식으로 이뤄짐.
- 특정시점에서는 원본 데이터와 복제된 데이터의 일관성은 보장하지 않는다.
- 데이터 정합성과 일관성을 보장하지 않는다.
- 위의 이유로 구성이 쉽고 빠르며 장애가 적은 복제 방식을 지원.
- MySQL 복제 순서
- 마스터 서버는 바이너리 로그를 활성화해 모든 데이터 처리 연산을 수행하는 SQL이 바이너리 로그에 저장되게 한다.
- 마스터 서버의 권한 설정에 슬레이브 서버의 리플리케이션 권한을 부여.
- 슬레이브 서버에 마스터 서버 정보를 입력하고 복제 모드로 실행.
- 복제 모드를 활성화할 경우 슬레이브 서버에는 I/O 스레드와 SQL 스레드가 실행된다.
- I/O 스레드는 마스터 서버에 접속해 마스터 서버의 바이너리 로그가 업데이트 되는 것을 모니터링하며,
업데이트가 발생하면 즉시 슬레이브 서버로 전송해 슬레이브 서버의 릴레이 로그에 저장한다. - SQL 스레드는 릴레이 로그를 계속 확인해 릴레이 로그에 새로운 레코드가 쓰여질 경우
슬레이브 서버에서 SQL문 그대로 실행해 마스터 서버와 동일한 데이터를 유지시키다.
- 마스터 서버는 오직 바이너리 로그에 데이터를 변경시키는 모든 SQL문을 저장하는 역할만 수행.
- 위의 이유로 슬레이브 서버의 숫자를 증가시켜도 마스터 서버의 부하에는 거의 영향을 미치지 않는다.
- 마스터-슬레이브 기본구성
- 1대 이상의 슬레이브 서버를 구성해 읽기 연산을 분산하는 용도로 사용.
- 백업이나 배치 작업용으로 사용.
- 슬레이브 서버가 계속해서 늘어나더라도 마스터 서버에 미치는 영향은 미미

- 양방향 마스터
- 마스터-마스터 복제 구조로 양쪽 서버 모두 복제를 위한 마스터 서버이면서 슬레이브 서버가 되는 구조.
- 액티브-액티브 또는 액티브-스탠바이 형태로 사용.
- 액티브-액티브 사용시 데이터의 중복과 순서에 매우 주의
- 프라이머리 키를 자동 증가(auto increment)로 설정하여 A서버는 1,3,5,7 형태의 홀수,
B서버는 2,4,6,8형태로 짝수가 되게 구성. - 서로 다른 테이블만 쓰기 연산을 수행하는 형태의 자동 증가 규칙을 적용하게 애플리케이션 조정.
- 액티브-스탠바이는 빠른 장애 복구를 위해 사용

- 링형 복제
- 서버를 서로 링 형태로 복제.
- 서버 중 어느 하나의 장애로 전체 구조가 깨진다.

- 피라미드형 복제
- 계층적인 구조로 중간에 슬레이브-마스터 서버가 존재하는 형태의 구성.
- 슬레이브 서버가 매우 많이 확장돼 마스터 서버에 부하가 생기는 것을 방지하기 위해
중간에 슬레이브-마스터 서버를 두어 이를 분산하는 구조. - 매우 넓은 나라의 경우 동부에 슬레이브-마스터 서버를 하나 배치하고
서부에 슬레이브-마스터 서버를 하나 배치해 전국적인 서비스 품질을 올리기 위해 사용가능.

MySQL 고가용성 구성
- 복제 방식은 구성이 쉽고 빠르고 단순하지만 기본적으로 고가용성을 지원하지 않는다.
- 복제 방식이 비동기 방식으로 이뤄지기 때문에 갑작스런 장애시 데이터 유실 가능성이 있다.
- 애플리케이션 레벨에서 마스터 서버 장애시 자동으로 슬레이브로 접속하게 해 가용성을 우회적으로 구현.
- 데이터베이스 자체에서 해결책을 제공하지 않는다.
- MySQL 가용성 솔루션

MySQL MMM
- Master-Master Replication Manager
- MySQL의 마스터-마스터 복제를 기본으로 한다.
- 최소 MySQL 서버 2대와 1대의 모니터링 서버 구성을 가지며, MySQL 서버 대수 N + 1개 만킁의 가상 IP가 기본적으로 필요하다.
- MySQL의 복제 특성을 가지고 있기 때문에 특정 시점의 원본 데이터와 복제 데이터의 일관성을 보장하지 않는다.
- Writer와 Reader라는 롤을 설정하고 각 롤에 가상 IP를 부여해 사용하는 방식으로, 애플리케이션에 투명하게 적용할 수 있다.
- 솔루션 자체가 데이터베이스와 시스템 상태 체크와 가상 IP의 컨트롤만을 다루게 돼 있어 데이터베이스 자체의
동작에 전혀 영향을 주지 않으며, MMM 자체에 장애가 발생해도 MySQL의 동작에는 전형 영향을 주지 않는다.

MySQL MMM 설치
- 리눅스나 오픈솔라리스
- 전체 소스는 Perl을 이용해 개발됐다.
- 3개의 에이전트로 구성
- mmmd_mon : 모니터링 서버에서 각 DB의 상태를 모니터링
- mmmd_agent : 각 MySQL 서버에서 수행되는 에이전트
- mmmd_control : 모니터링 서버에서 각 MySQL 서버의 상태를 제어
- 에이전트의 실행과 관련된 환경 설정 파일은 /etc/mysql-mmm에 설치.
- mmm_common.conf : 각 호스트에 공통적으로 적용되는 설정 파일
- mmm_agent.conf : 각 데이터베이스 서버에서 사용할 에이전트 설정 파일
- mmm_mon.conf : 모니터 서버에서 사용하는 설정 파일
- 에이전트의 실행 파일과 각 데이터베이스 서버에서 MMM을 실행하기 위한 파일은 /etc/init.d에 설치.
- mysql-mmm-agent : 각 데이터베이스 서버에서 실행
- mysql-mmm-monitor : 모니터링 서버에서 실행
- 마스터와 슬레이브 서버의 상태를 제어하는 파일은 /usr/sbin/mmm_control에 설치
- mmmd_agent : 각 데이터베이스 서버에서 수행되는 에이전트
- mmmd_control : 모니터링 서버에서 각 데이터 베이스 서버의 상태를 제어
- 실습 환경 p.239 ~ 442 참고
NoSQL 사용시 주의 사항
- NoSQL은 범용적인 저장소가 아니다.
- 프로그램, 데이터 모델 경험이 부족하다.
- 관리도구가 부족하다.
- 시스템 자원 사용을 모니터링해야 한다.
- 가능하면 코드를 분석하라.
- 커뮤니티에 적극적으로 참여하라
- 성능과 안정성 테스트는 실제 데이터를 이용하라.
- 솔루션에서 제공하는 자료를 맹신하지 마라.